package com.eportal.util;

import com.bcloud.msg.http.HttpSender;
import org.apache.log4j.Logger;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.Properties;

/**
 * 发送短信工具
 *
 * @author wangk
 */
@Component
public class SmsHelper {

	private static String SMS_SERVER_URL = "";
	private static String SMS_ACCOUNT = "";
	private static String SMS_PASSWORD = "";
	private static MdExpiringMap<String, String> SMS_VALID_CACHE = null;
	protected static Logger log = Logger.getLogger(SmsHelper.class);


	static{
		try {
//			Properties pps = new Properties();
//			InputStream in = SmsHelper.class.getClassLoader().getResourceAsStream("/sms.properties");
//			pps.load(in);
			Properties pps= PropertiesLoaderUtils.loadAllProperties("sms.properties");//todo Created by Saber on 2017/7/14 下午12:29
			SMS_SERVER_URL = pps.getProperty("sms.server.url");
			SMS_ACCOUNT = pps.getProperty("sms.account");
			SMS_PASSWORD = pps.getProperty("sms.password");
			// 参数1：验证码的存活时间，一般稍微大于我们设置的验证码有效时间。
			// 参数2：检查验证码是否过期的间隔时间，这里对时间精度要求不高，一般10s-60s。
			SMS_VALID_CACHE = new MdExpiringMap<String, String>(21 * 60, 30);
//			in.close();
		} catch (IOException e) {
			log.error("短信服务初始化异常",e);
		}
	}

	public SmsHelper() {

	}

	public static String sendSMSVaildCode(String phone, String code) throws Exception {
		if(code == null || code.trim().length() == 0) {
			code = "" + System.currentTimeMillis();
			code = code.substring(code.length() - 4);
		}

		boolean needstatus = true;
		Object product = null;
		Object extno = null;
		byte minDiffSeconds = 60;
		String content = "亲爱的用户，您的验证码是" + code + "，5分钟内有效。";
		String returnString = null;
		Long lastSendTime = SMS_VALID_CACHE.getCreateTime(phone);

		try {
			if(lastSendTime != null) {
				long e = (new Date()).getTime() - lastSendTime.longValue();
				if(e < (long)(minDiffSeconds * 1000) && e >= 0L) {
					throw new Exception("2次发送时间间隔应大于" + minDiffSeconds + "秒！");
				}
			}

			returnString = HttpSender.batchSend(SMS_SERVER_URL, SMS_ACCOUNT, SMS_PASSWORD, phone, content, needstatus, (String)product, (String)extno);
			pushIntoSMSValidCache(phone, code);

			try {
			/*	Api_CONFINE_SMSC_A1_Request e1 = new Api_CONFINE_SMSC_A1_Request();
				e1.setMobile(phone);
				e1.setSend_time(System.currentTimeMillis() / 1000L + "");
				e1.setSend_num("1");
				Tresponse response = new Tresponse() {
				};
				e1.doBuiness(SysListner.dbService, response, e1.getPageno());*/
			} catch (Exception var11) {
				log.error(var11.getMessage());
			}

			checkSmsReturnCode(returnString);
			return code;
		} catch (Exception var12) {
			throw new Exception("短信验证码发送失败，最终错误：" + var12.getMessage());
		}
	}


	public static String sendSMSVaildCode(String type,String phone,String content, String code) throws Exception {
		if(code == null || code.trim().length() == 0) {
			code = "" + System.currentTimeMillis();
			code = code.substring(code.length() - 4);
		}

		boolean needstatus = true;
		Object product = null;
		Object extno = null;
		byte minDiffSeconds = 60;
		String returnString = null;
		Long lastSendTime = SMS_VALID_CACHE.getCreateTime(phone);
		try {
			if(lastSendTime != null) {
				long e = (new Date()).getTime() - lastSendTime.longValue();
				if(e < (long)(minDiffSeconds * 1000) && e >= 0L) {
					throw new Exception("2次发送时间间隔应大于" + minDiffSeconds + "秒！");
				}
			}

			returnString = HttpSender.batchSend(SMS_SERVER_URL, SMS_ACCOUNT, SMS_PASSWORD, phone, content, needstatus, (String)product, (String)extno);
			pushIntoSMSValidCache(phone, code,type);

			try {
			/*	Api_CONFINE_SMSC_A1_Request e1 = new Api_CONFINE_SMSC_A1_Request();
				e1.setMobile(phone);
				e1.setSend_time(System.currentTimeMillis() / 1000L + "");
				e1.setSend_num("1");
				Tresponse response = new Tresponse() {
				};
				e1.doBuiness(SysListner.dbService, response, e1.getPageno());*/
			} catch (Exception var11) {
				log.error(var11.getMessage());
			}

			checkSmsReturnCode(returnString);
			return code;
		} catch (Exception var12) {
			throw new Exception("短信验证码发送失败，最终错误：" + var12.getMessage());
		}
	}

	public static String sendSMSVaildCode(String phone) throws Exception {
		// 生成校验码
		String code = "" + System.currentTimeMillis();
		code = code.substring(code.length() - 6);

		boolean needstatus = true;// 是否需要状态报告，需要true，不需要false
		String product = null;// 产品ID
		String extno = null;// 扩展码
		int minDiffSeconds = 60; // 2次验证短信的最短间隔时间
		String content = "尊敬的用户，您的验证码是" + code + "，20分钟内有效。";// 短信内容
		log.info("phone="+content+",content="+content);
		String returnString = null;
		Long lastSendTime = SMS_VALID_CACHE.getCreateTime(phone);
		try {
			if (lastSendTime != null) {
				long diff = new Date().getTime() - lastSendTime;
				if (diff < minDiffSeconds * 1000 && diff >= 0) {
					throw new Exception("2次发送时间间隔应大于" + minDiffSeconds + "秒！");
				}
			}
			returnString = HttpSender.batchSend(SMS_SERVER_URL, SMS_ACCOUNT, SMS_PASSWORD, phone, content, needstatus,
					product, extno);
			pushIntoSMSValidCache(phone, code);
			try {
				// 把短信记录插入数据库
			/*	Confine_smsc confine_smsc = new Confine_smsc();
				confine_smsc.setMobile(phone);//登录帐号
				confine_smsc.setSendTime(System.currentTimeMillis());//发送时间
				confine_smsc.setSendNum(1l);//发送数量
				SysListner.dbService.confine_smsc_InsertSelective(confine_smsc);	*/
			} catch (Exception e) {
				log.error("记录插入数据库失败",e);
			}
			checkSmsReturnCode(returnString);
		} catch (Exception e) {
			log.error("发送短信失败", e);
			throw new Exception(e);
		}
		return code;
	}

	public static void sendByPhone(String content, String phone) throws Exception {
		boolean needstatus = true;
		Object product = null;
		Object extno = null;
		String returnString = null;

		try {
			returnString = HttpSender.batchSend(SMS_SERVER_URL, SMS_ACCOUNT, SMS_PASSWORD, phone, content, needstatus, (String)product, (String)extno);
			checkSmsReturnCode(returnString);
		} catch (Exception var7) {
			throw new Exception("短信发送失败，最终错误：" + var7.getMessage());
		}
	}

	private static String TYPE_DEAULT = "default";
	private static void pushIntoSMSValidCache(String phone, String code) {
		pushIntoSMSValidCache(phone, code, TYPE_DEAULT);
	}

	private static void pushIntoSMSValidCache(String phone, String code,String type) {
		SMS_VALID_CACHE.put(getKey(type, phone), code);
	}

	public static String getCode(String phone) {
		return (String)SMS_VALID_CACHE.get(phone);
	}


	public static String getKey(String type,String phone){
		return phone + "_" + type;
	}

	/*public static int validatePhone(String phone) {
		TBaseExample param = new TBaseExample();
		Criteria c = param.createCriteria();
		c.addCriterion(" MOBILE = \'" + phone + "\'");
		int result = SysListner.dbhelper.getDbService().to
		return result;
	}

	public static int validatePhone(String phone, Long appid) {
		TBaseExample param = new TBaseExample();
		Criteria c = param.createCriteria();
		c.addCriterion(" MOBILE = \'" + phone + "\'");

		if(appid!=null){
			c.addCriterion(" appid="+appid+"");
		}else{
			c.addCriterion(" appid is null");
		}
		int result = SysListner.dbhelper.getDbService().lock_user_SelectByExample(param).size();
		return result;
	}*/

	public static boolean checkSMSValidCache(String phone, String code) {
		return checkSMSValidCache(TYPE_DEAULT, phone, code);
	}

	public static boolean checkSMSValidCache(String type,String phone, String code) {
		String vcode = (String)SMS_VALID_CACHE.get(getKey(type, phone));
		return vcode != null && vcode.equals(code);
	}

	public static boolean checkSMSValidCache(String type,String phone, String code,Long exp) {
		Long ctime = SMS_VALID_CACHE.getCreateTime(getKey(type, phone));
		if(ctime!=null){
			if((System.currentTimeMillis()-ctime)<exp){	//检查验证码是否在有效期内
				return checkSMSValidCache(type, phone, code);
			}
		}
		return false;
	}

	public static void remove(String type,String phone) {
		SMS_VALID_CACHE.remove(getKey(type, phone));
	}

	private static boolean checkSmsReturnCode(String returnString) throws Exception {
		String code = null;
		String[] returnArr = returnString.split(",");
		if(returnArr.length > 1) {
			code = returnArr[1];
		}

		if(code == null) {
			log.error("解析短信返回码失败：" + returnString);
			return true;
		} else {
			String content = null;
			if(code.indexOf("0") == 0) {
				return true;
			} else {
				if("101".equals(code)) {
					content = "无此用户";
				} else if("102".equals(code)) {
					content = "密码错";
				} else if("103".equals(code)) {
					content = "提交过快（提交速度超过流速限制";
				} else if("104".equals(code)) {
					content = "系统忙（因平台侧原因，暂时无法处理提交的短信）";
				} else if("105".equals(code)) {
					content = "敏感短信（短信内容包含敏感词）";
				} else if("106".equals(code)) {
					content = "消息长度错（>536或<=0)";
				} else if("107".equals(code)) {
					content = "包含错误的手机号码";
				} else if("108".equals(code)) {
					content = "手机号码个数错（群发>50000或<=0;单发>200或<=0）";
				} else if("109".equals(code)) {
					content = "无发送额度（该用户可用短信数已使用完）";
				} else if("110".equals(code)) {
					content = "不在发送时间内";
				} else if("111".equals(code)) {
					content = "超出该账户当月发送额度限制";
				} else if("112".equals(code)) {
					content = "无此产品，用户没有订购该产品";
				} else if("113".equals(code)) {
					content = "extno格式错（非数字或者长度不对）";
				} else if("115".equals(code)) {
					content = "自动审核驳回";
				} else if("116".equals(code)) {
					content = "签名不合法，未带签名（用户必须带签名的前提下）";
				} else if("117".equals(code)) {
					content = "IP地址认证错,请求调用的IP地址不是系统登记的IP地址";
				} else if("118".equals(code)) {
					content = "用户没有相应的发送权限";
				} else if("119".equals(code)) {
					content = "用户已过期";
				} else if("120".equals(code)) {
					content = "短信内容不在白名单中";
				} else {
					log.error("不能识别的短信返回码：" + returnString);
				}

				if(content != null) {
					throw new Exception(content);
				} else {
					return false;
				}
			}
		}
	}

	static {
		try {
//			Properties e = new Properties();
//			InputStream in = SmsHelper.class.getClassLoader().getResourceAsStream("/sms.properties");
//			e.load(in);
			Properties e= PropertiesLoaderUtils.loadAllProperties("sms.properties");//todo Created by Saber on 2017/7/14 下午12:29
			SMS_SERVER_URL = e.getProperty("sms.server.url");
			SMS_ACCOUNT = e.getProperty("sms.account");
			SMS_PASSWORD = e.getProperty("sms.password");
			SMS_VALID_CACHE = new MdExpiringMap(930, 30);
		} catch (IOException var2) {
			log.error("短信服务初始化异常：" + var2.getMessage());
		}

	}


}
